// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) 
// Source File Name:   Security.java

package com.boci.common.util;

import gnu.crypto.sig.rsa.RSA;
import java.io.*;
import java.math.BigInteger;
import java.net.URL;
import java.net.UnknownHostException;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.security.spec.X509EncodedKeySpec;
import java.util.Calendar;
import java.util.Date;
import java.util.logging.Logger;
import javax.net.ssl.*;

// Referenced classes of package com.boci.common.util:
//            CMLogger

public class Security
{

    public static Security getInstance()
        throws Exception
    {
        if(instance == null)
        {
            instance = new Security();
            try
            {
                Security _tmp = instance;
                PublicKey publicKey = loadPublicKeyFromJar("/com/boci/common/resources/keys/pubkey.cer");
                if(publicKey != null)
                    instance.setPublicKey(publicKey);
                else
                    throw new Exception("Fail to load public key");
            }
            catch(Exception e)
            {
                throw e;
            }
        }
        return instance;
    }

    private Security()
    {
    }

    public PublicKey getPublicKey()
    {
        return publicKey;
    }

    public void setPublicKey(PublicKey publicKey)
    {
        this.publicKey = publicKey;
    }

    public String encrypt(String pMsg)
    {
        BigInteger bigMsg = new BigInteger(1, pMsg.getBytes());
        BigInteger bigCipher = RSA.encrypt(publicKey, bigMsg);
        return bigCipher.toString();
    }

    public static Certificate[] getServerCertificate(String requestURL)
        throws IOException
    {
        URL url = new URL(requestURL);
        int port = url.getPort();
        if("https".equals(url.getProtocol()))
        {
            if(port != -1)
                return getServerCertificate(url.getHost(), port);
            else
                return getServerCertificate(url.getHost(), 443);
        } else
        {
            return getServerCertificate(url.getHost(), url.getPort());
        }
    }

    public static Certificate[] getServerCertificate(String hostname, int port)
        throws IOException
    {
        SSLSocket socket = null;
        Certificate serverCerts[];
        try
        {
            SSLSocketFactory factory = HttpsURLConnection.getDefaultSSLSocketFactory();
            socket = (SSLSocket)factory.createSocket(hostname, port);
            socket.startHandshake();
            serverCerts = socket.getSession().getPeerCertificates();
        }
        catch(UnknownHostException e)
        {
            throw e;
        }
        catch(SSLPeerUnverifiedException e)
        {
            throw e;
        }
        catch(IOException e)
        {
            throw e;
        }finally{
        	if(socket != null)
	            try
	            {
	                socket.close();
	            }
	            catch(IOException e)
	            {
	                throw e;
	            }
        }
        return serverCerts;
    }

    public static boolean isValidServerCert(String requestURL, String subject, String issuer)
        throws IOException
    {
        boolean resultFlag = true;
        Date currDate = Calendar.getInstance().getTime();
        logger.info((new StringBuilder()).append("Input Subject=").append(subject).toString());
        logger.info((new StringBuilder()).append("Input Issuer=").append(issuer).toString());
        logger.info((new StringBuilder()).append("Curr Date=").append(currDate).toString());
        Certificate certs[] = getServerCertificate(requestURL);
        if(certs != null)
        {
            logger.info((new StringBuilder()).append(certs.length).append(" certs returned").toString());
            X509Certificate cert = (X509Certificate)certs[0];
            logger.info((new StringBuilder()).append("Subject DN:").append(cert.getSubjectDN()).toString());
            logger.info((new StringBuilder()).append("Issuer:").append(cert.getIssuerDN()).toString());
            logger.info((new StringBuilder()).append("Valid from:").append(cert.getNotBefore()).toString());
            logger.info((new StringBuilder()).append("Valid until:").append(cert.getNotAfter()).toString());
            if(currDate.after(cert.getNotBefore()) && currDate.before(cert.getNotAfter()))
            {
                logger.info("within valid period");
            } else
            {
                logger.info("not within valid period");
                resultFlag = false;
            }
            if(subject.equals(cert.getSubjectDN().toString()))
            {
                logger.info("valid subject");
            } else
            {
                logger.info("invalid subject");
                resultFlag = false;
            }
            if(issuer.equals(cert.getIssuerDN().toString()))
            {
                logger.info("valid issuer");
            } else
            {
                logger.info("invalid issuer");
                resultFlag = false;
            }
        }
        return resultFlag;
    }

    private static PublicKey loadPublicKeyFromJar(String pFilePath)
        throws Exception
    {
        PublicKey loadedPublicKey;
        InputStream inPubKey;
        ByteArrayOutputStream outPubKey;
        loadedPublicKey = null;
        inPubKey = null;
        outPubKey = null;
        try
        {
            inPubKey = com.boci.common.util.Security.class.getResourceAsStream(pFilePath);
            outPubKey = new ByteArrayOutputStream();
            byte bytes[] = new byte[1024];
            for(int read = 0; (read = inPubKey.read(bytes)) >= 0;)
                outPubKey.write(bytes, 0, read);

            X509EncodedKeySpec X509KeySpec = new X509EncodedKeySpec(outPubKey.toByteArray());
            KeyFactory keyFactoryEngine = KeyFactory.getInstance("RSA");
            loadedPublicKey = keyFactoryEngine.generatePublic(X509KeySpec);
        }
        catch(Exception e)
        {
            throw e;
        }finally{
            inPubKey.close();
            outPubKey.close();        	
        }
        return loadedPublicKey;
    }

    public static void setTrustStore(String url)
    {
        System.setProperty("javax.net.ssl.trustStore", url);
    }

    private static Logger logger = CMLogger.getInstance();
    private PublicKey publicKey;
    private static Security instance;

}
